package com.itheima.game10;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

/*
    图片上移动,就是让0号图片和下方法图片交换
    0号图片坐标为
        datas[x0][y0]
    0号图片下方法图片坐标为
       datas[x0+1][y0]

       在"上"的按钮事件的代码中
            1.边界处理, 当x0=3,不能继续向上移动
            2.交换0号图片和下方图片 (代码先抄下来,慢慢理解)
                datas[x0][y0] = datas[x0+1][y0]
                datas[x0+1][y0] = 0;
                x0 = x0 +1
           3.编写并调用重绘的方法rePainView()

           重绘的方法rePainView()
           1.将imagePanel提升到成员位置
           2.调用imagePanel的removeAll()方法溢出所有组件
           3.拼图重绘的代码(复制之前写好的)
           4.调用imagePanel的repaint()的方法重会窗体

           图片左移规则
                    边界y0=3
                    datas[x][y0] = datas[x0][y0+1];
                    datas[x0][y0+1]=0;
                    y0++;
          图片下移规则
                    边界x0==0
                    datas[x0][y0] = datas[x0-1][y0];
                    datas[x0-1][y0] = 0;
                    x0--;
           图片右移规则
                    边界y0==0
                    datas[x0][y0] = datas[x0][y0-1];
                    datas[x0][y0 - 1] = 0;
                    y0--;


                    求助按钮
                        1.按钮求助事件底阿妈中环,提供方法success(),方法中完成
                            将二维数组datas元素重置为,编号1-16图片
                            设置上左下右按钮失效
                        2.调用重绘制的方法rePainView()

 * */
public class PictureFrame extends JFrame {

    //定义二维数组,表示图片的编号--->用格式1---->简化格式-->静态赋值
    //对应封装思想
    private int[][] datas = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };//用0替代掉16

    /*
     * 成员变量, 用于记录0号图片的位置
     *       x0 :在哪一个一维数组中
     *       y0: 在一维数组中的那个位置
     *
     * */
    private int x0;
    private int y0;
    //上下左右,求助按钮,重置等按钮,提升到成员位置
    //对应封装思想,进行private修饰
    private JLabel canZhaoLabel;
    private JButton shangButton;
    private JButton zouButton;
    private JButton xiaButton;
    private JButton youButton;
    private JButton qiuzhuButton;
    private JButton chongzhiButton;
    private JPanel imagePanel;


    //重绘制方法
    private void rePainView() {
        //1.将paintView中的imagePanel提升到成员位置
        //2.调用imagePanel的removeAll()方法移除所有组件
        imagePanel.removeAll();//-------->就可以理解成将之前的步骤全部重置,就是把面板上的东西全部删除(图片按钮)

        //3.拼图重绘代码(之前已经写好)
        for (int i = 0; i < datas.length; i++) {
            for (int j = 0; j < datas[i].length; j++) {
                //创建JLabel对象
                JLabel imageLabel = new JLabel(new ImageIcon("day09\\imgs\\" + datas[i][j] + ".png"));
                //设置大小和位置
                imageLabel.setBounds(j * 90, i * 90, 90, 90);
                //将图片加载的JPanel中
                imagePanel.add(imageLabel);
            }
        }
        //再将JPanel添加到窗体上
        this.add(imagePanel);
        //4.调用imagePanel的repaint()方法重绘窗体
        imagePanel.repaint();//java提供-----------就是刷新


        /*
简单易懂的解释：
这两行代码的作用是 清空面板上的所有内容，并立即刷新显示，相当于：

imagePanel.removeAll();
➠ "把面板上的所有东西（图片、按钮等）全部删掉！"
（就像把白板上的所有图画和文字全部擦掉）

imagePanel.repaint();
➠ "立刻重新画一遍面板（现在它已经是空的了）！"
（告诉系统："白板擦完了，你现在可以刷新显示了！"）

类比场景：
假设 imagePanel 是一块白板：

removeAll() → 你把白板上的所有字和画都擦掉了（但别人暂时还看不到变化）。

repaint() → 你大喊一声："刷新！"，这时大家才会看到白板变成空白。        *
        *
        * */
    }

    //求助实现方法
    private void success() {
        //将二维数组datas元素重置为,编号为1到16的图片
        datas = new int[][]{
                {1, 2, 3, 4},
                {5, 6, 7, 8},
                {9, 10, 11, 12},
                {13, 14, 15, 16}
        };

        //设置上下左右按钮失效
        shangButton.setEnabled(false);
        youButton.setEnabled(false);
        xiaButton.setEnabled(false);
        zouButton.setEnabled(false);
        rePainView();
        }

        //空参构造
    public PictureFrame() {
            //用于窗体设置
            initFrame();
            //数组的打乱一定要在图片加载之前
            randomDates();
            //绘制基本组件
            printView();
            //调用添加事件的方法
            addButtonEvent();
            //设置窗体可见
            this.setVisible(true);
        }

        //给按钮添加点击事件
        public void addButtonEvent () {
            shangButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    //1.边界处理,当x0==3,就代表0号图片在最底下, 不能进行上移
                    if (x0 == 3) {
                        System.out.println("0号图片已经在最低下了,不能进行上移");
                        return;
                    }
                    datas[x0][y0] = datas[x0 + 1][y0];
                    datas[x0 + 1][y0] = 0;
                    x0 = x0 + 1;
                    rePainView();

                }
            });
            zouButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    //1.边界处理,当y0==3时,就代表0号图片子在最右边,不能再进行左移动
                    if (y0 == 3) {
                        System.out.println("0号图片已经子啊最右边了,不能在进行左移了");
                        return;
                    }
                    datas[x0][y0] = datas[x0][y0 + 1];
                    datas[x0][y0 + 1] = 0;
                    y0 = y0 + 1;
                    rePainView();
                }
            });
            xiaButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    //1.边界处理,当x0==0时,就就代表0号图片在最上面了,不能在进行下移了
                    if (x0 == 0) {
                        System.out.println("空白图片已经在最下面了,不能再往下移动了");
                        return;
                    }
                    datas[x0][y0] = datas[x0 - 1][y0];
                    datas[x0 - 1][y0] = 0;
                    x0 = x0 - 1;
                    rePainView();
                }
            });
            youButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    //边界值判断,当y0==0时,就代表0号图片已经在最左边了,无法再进行右移
                    if (y0 == 0) {
                        System.out.println("图片已经在最左边无法再右移动");
                        return;
                    }
                    datas[x0][y0] = datas[x0][y0 - 1];
                    datas[x0][y0 - 1] = 0;
                    y0 = y0 - 1;
                    rePainView();
                }
            });
            chongzhiButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

                    //重置原始的数组
                    datas = new int[][]{
                            {1, 2, 3, 4},
                            {5, 6, 7, 8},
                            {9, 10, 11, 12},
                            {13, 14, 15, 0} //如果用户点击重置,目的是重新开始游戏,加入0号图片
                    };
                    //打乱数组
                    randomDates();
                    //重绘
                    rePainView();
                    //设置上左下右按钮生效
                    shangButton.setEnabled(true);
                    zouButton.setEnabled(true);
                    xiaButton.setEnabled(true);
                    youButton.setEnabled(true);
                }
            });
            qiuzhuButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

                    success();
                }
            });
        }

        //面向对象思想,如果要完成一个功能,就是一个成员方法---------->注意没有static关键字
        public void randomDates () {
            //创建随机数对象
            Random r = new Random();
            //遍历数组
            for (int i = 0; i < datas.length; i++) {
                for (int j = 0; j < datas[i].length; j++) {
                    //获取两个随机索引
                    int y = r.nextInt(datas.length);
                    int x = r.nextInt(datas[i].length);

                    //进行数据交换
                    int temp = datas[i][j];
                    datas[i][j] = datas[x][y];
                    datas[x][y] = temp;
                }
            }
            /*
             * 打乱后的数组, 定位0号图片的位置
             *   循环标号: 给循环起名字, 然后使用break 名字;结束循环
             *
             *
             *
             * */
            //遍历数组记录0号图片的位置
            //给循环起一个名字
            lo:
            for (int i = 0; i < datas.length; i++) {
                for (int j = 0; j < datas[i].length; j++) {
                    //判断,如果找到0号图片的位置就结束循环
                    if (datas[i][j] == 0) {
                        x0 = i;
                        y0 = j;
                        break lo;//----结束外层循环
                    }
                }
            }
            //查看结果
            System.out.println(x0 + "," + y0);

        }


        //方法initFrame()
        //用于窗体的基本设置
        public void initFrame () {
            //窗体大小
            this.setSize(960, 565);
            //窗体标题
            this.setTitle("动漫拼图");

            //窗体居中
            this.setLocationRelativeTo(null);

            //窗体关闭时退出应用程序
            this.setDefaultCloseOperation(3);
            //窗体位于其他窗口之上
            this.setAlwaysOnTop(true);
            //取消默认布局
            this.setLayout(null);


        }

        //绘制窗体的基本组件 printView
        //成员方法,功能
   /* 1：定义方法，用于窗体上的组件绘制：paintView()

            2：按照如下组件绘制
            标题图片
            面板图片，存储着将来要移动的图片
            参照图
            上按钮
            左按钮
            下按钮
            右按钮
            求助按钮
            重置按钮

        3：在构造方法中调用paintView()方法*/
        public void printView () {
            //标题组件
            JLabel titleLabel = new JLabel(new ImageIcon("day09\\imgs\\title.png"));
            //设置大小
            titleLabel.setBounds(245, 27, 232, 57);
            //添加到窗体上
            this.add(titleLabel);


            //创建JPanel容器面板 用于拼图的部分
            imagePanel = new JPanel();
            //取消默认布局
            imagePanel.setLayout(null);//_------>注意这个,没有取消默认布局就会有bug ,要调用刷新方法
            //设置大小
            imagePanel.setBounds(150, 114, 360, 360);
            //遍历for循环得到所有图片
            for (int i = 0; i < datas.length; i++) {
                for (int j = 0; j < datas[i].length; j++) {
                    //通过JLabel加载图片
                    JLabel imageLabel = new JLabel(new ImageIcon("day09\\imgs\\" + datas[i][j] + ".png"));
                    //设置图片的大小
                    imageLabel.setBounds(j * 90, i * 90, 90, 90);
                    //将图片加到面板上
                    imagePanel.add(imageLabel);
                }
            }
            //将JPanel面板加到窗体上
            this.add(imagePanel);


            //参照图
            canZhaoLabel = new JLabel(new ImageIcon("day09\\imgs\\canzhaotu.png"));
            //设置大小
            canZhaoLabel.setBounds(574, 114, 122, 121);
            //将图片添加到窗体中
            this.add(canZhaoLabel);

            //上按钮
            shangButton = new JButton(new ImageIcon("day09\\imgs\\shang.png"));
            //设置大小和位置
            shangButton.setBounds(732, 265, 57, 57);
            //将按钮添加到窗体中
            this.add(shangButton);

            //左按钮
            zouButton = new JButton(new ImageIcon("day09\\imgs\\zuo.png"));
            //设置大小和位置
            zouButton.setBounds(650, 347, 57, 57);
            //将按钮添加到窗体中
            this.add(zouButton);

            //下按钮
            xiaButton = new JButton(new ImageIcon("day09\\imgs\\xia.png"));
            //设置大小和位置
            xiaButton.setBounds(732, 347, 57, 57);
            //将按钮添加到窗体中
            this.add(xiaButton);

            //右按钮
            youButton = new JButton(new ImageIcon("day09\\imgs\\you.png"));
            //设置大小和位置
            youButton.setBounds(813, 347, 57, 57);
            //将按钮添加到窗体中
            this.add(youButton);

            //求助按钮
            qiuzhuButton = new JButton(new ImageIcon("day09\\imgs\\qiuzhu.png"));
            //设置大小和位置
            qiuzhuButton.setBounds(626, 444, 108, 45);
            //将该按钮添加到窗体中
            this.add(qiuzhuButton);

            //重置按钮
            chongzhiButton = new JButton(new ImageIcon("day09\\imgs\\chongzhi.png"));
            //设置按钮大小和位置
            chongzhiButton.setBounds(786, 444, 108, 45);
            //将按钮添加到窗体中
            this.add(chongzhiButton);

            //背景图:必须写在最后
            JLabel backgroudLabel = new JLabel(new ImageIcon("day09\\imgs\\background.png"));
            //设置大小和位置
            backgroudLabel.setBounds(0, 0, 968, 530);

        }

    }
